package com.heima.common.aliyun;

import com.alibaba.fastjson.JSON;
import com.aliyun.green20220302.Client;
import com.aliyun.green20220302.models.*;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * @Author: xsz
 * @DateTime: 2024/1/28 19:17
 **/

@Getter
@Setter
@Component
@ConfigurationProperties(prefix = "aliyun")
public class GreenImageScanPlus {

    private String accessKeyId;
    private String secret;
    private String scenes;

    //服务是否部署在vpc上
    public static boolean isVPC = false;

    //文件上传token endpoint->token
    public static Map<String, DescribeUploadTokenResponseBody.DescribeUploadTokenResponseBodyData> tokenMap = new HashMap<>();

    //上传文件请求客户端
    public static OSS ossClient = null;

    /**
     * 创建请求客户端
     *
     * @param accessKeyId
     * @param accessKeySecret
     * @param endpoint
     * @return
     * @throws Exception
     */
    public static Client createClient(String accessKeyId, String accessKeySecret, String endpoint) throws Exception {
        Config config = new Config();
        config.setAccessKeyId(accessKeyId);
        config.setAccessKeySecret(accessKeySecret);
        // 设置http代理。
        // config.setHttpProxy("http://10.10.xx.xx:xxxx");
        // 设置https代理。
        // config.setHttpsProxy("https://10.10.xx.xx:xxxx");
        // 接入区域和地址请根据实际情况修改
        config.setEndpoint(endpoint);
        return new Client(config);
    }

    /**
     * 创建上传文件请求客户端
     *
     * @param tokenData
     * @param isVPC
     */
    public static void getOssClient(DescribeUploadTokenResponseBody.DescribeUploadTokenResponseBodyData tokenData, boolean isVPC) {
        //注意，此处实例化的client请尽可能重复使用，避免重复建立连接，提升检测性能。
        if (isVPC) {
            ossClient = new OSSClientBuilder().build(tokenData.ossInternalEndPoint, tokenData.getAccessKeyId(), tokenData.getAccessKeySecret(), tokenData.getSecurityToken());
        } else {
            ossClient = new OSSClientBuilder().build(tokenData.ossInternetEndPoint, tokenData.getAccessKeyId(), tokenData.getAccessKeySecret(), tokenData.getSecurityToken());
        }
    }

    /**
     * 上传文件
     * @param imageData
     * @param tokenData
     * @return
     * @throws Exception
     */


    public static String uploadFile(byte[] imageData, DescribeUploadTokenResponseBody.DescribeUploadTokenResponseBodyData tokenData) throws Exception {
        String objectName = tokenData.getFileNamePrefix() + UUID.randomUUID() + ".png"; // 以png格式为例

        // 使用ByteArrayInputStream包装二进制数据
        ByteArrayInputStream inputStream = new ByteArrayInputStream(imageData);

        // 创建PutObjectRequest，将ByteArrayInputStream传递给它
        PutObjectRequest putObjectRequest = new PutObjectRequest(tokenData.getBucketName(), objectName, inputStream);

        // 上传文件
        ossClient.putObject(putObjectRequest);

        // 关闭输入流
        inputStream.close();

        return objectName;
    }


    public static ImageModerationResponse invokeFunction(byte[] imageData,String accessKeyId, String accessKeySecret, String endpoint) throws Exception {
        //注意，此处实例化的client请尽可能重复使用，避免重复建立连接，提升检测性能。
        Client client = createClient(accessKeyId, accessKeySecret, endpoint);
        RuntimeOptions runtime = new RuntimeOptions();


        String bucketName = null;
        DescribeUploadTokenResponseBody.DescribeUploadTokenResponseBodyData uploadToken = tokenMap.get(endpoint);
        //获取文件上传token
        if (uploadToken == null || uploadToken.expiration <= System.currentTimeMillis() / 1000) {
            DescribeUploadTokenResponse tokenResponse = client.describeUploadToken();
            uploadToken = tokenResponse.getBody().getData();
            bucketName = uploadToken.getBucketName();
        }
        //上传文件请求客户端
        getOssClient(uploadToken, isVPC);

        //上传文件
        String objectName = uploadFile(imageData, uploadToken);

        // 检测参数构造。
        Map<String, String> serviceParameters = new HashMap<>();
        //文件上传信息
        serviceParameters.put("ossBucketName", bucketName);
        serviceParameters.put("ossObjectName", objectName);
        serviceParameters.put("dataId", UUID.randomUUID().toString());

        ImageModerationRequest request = new ImageModerationRequest();
        // 图片检测service：内容安全控制台图片增强版规则配置的serviceCode，示例：baselineCheck
        // 支持service请参考：https://help.aliyun.com/document_detail/467826.html?0#p-23b-o19-gff
        request.setService("baselineCheck");
        request.setServiceParameters(JSON.toJSONString(serviceParameters));

        ImageModerationResponse response = null;
        try {
            response = client.imageModerationWithOptions(request, runtime);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }

    /**
     * 审核图片二进制列表，一旦有一个图片违规，则返回true，否则返回false
     * @param imageDatas
     * @return
     * @throws Exception
     */
    public boolean greenImageScanPlus(List<byte[]> imageDatas) throws Exception {
        for (byte[] imageData : imageDatas) {
            /**
             * 阿里云账号AccessKey拥有所有API的访问权限，建议您使用RAM用户进行API访问或日常运维。
             * 常见获取环境变量方式：
             * 方式一：
             *     获取RAM用户AccessKey ID：System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
             *     获取RAM用户AccessKey Secret：System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
             * 方式二：
             *     获取RAM用户AccessKey ID：System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_ID");
             *     获取RAM用户AccessKey Secret：System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
             */

            // 接入区域和地址请根据实际情况修改。
            ImageModerationResponse response = invokeFunction(imageData,accessKeyId, secret, "green-cip.cn-shanghai.aliyuncs.com");
            try {
                // 自动路由。
                if (response != null) {
                    //区域切换到cn-beijing。
                    if (500 == response.getStatusCode() || (response.getBody() != null && 500 == (response.getBody().getCode()))) {
                        // 接入区域和地址请根据实际情况修改。
                        response = invokeFunction(imageData,accessKeyId, secret, "green-cip.cn-beijing.aliyuncs.com");
                    }
                }
                // 检测结果。
                if (response != null && response.getStatusCode() == 200) {
                    // 根据实际需求判断是否违规，这里使用一个简单的示例，假设只要有一个结果是违规的就返回 true。
                    if (hasViolations(response)) {
                        return true;
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
                // 如果发生异常，默认当做违规处理，根据实际需求进行处理。
                return true;
            }

        }

        return false;
    }

    private boolean hasViolations(ImageModerationResponse response) {
        return response.getBody().getData().getResult().stream()
                .anyMatch(result -> result.getLabel().equals("pornographic_adultContent") && result.getConfidence() > 80);
    }


}
